<!DOCTYPE html>
<html lang="en">
	<head>
		<meta charset="UTF-8" />
		<meta http-equiv="X-UA-Compatible" content="IE=edge" />
		<meta name="viewport" content="width=device-width, initial-scale=1.0" />
		<title>Document</title>
	</head>
	<style>
		.box {
			width: 100px;
			height: 100px;
			background-color: red;
		}
	</style>
	<body>
		<audio src="./DiscoYes.mp3" controls></audio>
		<canvas class="cvs"></canvas>
		<button id="playBtn">play</button>
	</body>
	<script>
		const colors = ['#332FD0', '#F10086', '#F0A500', '#FFF89A', '#FF1818', '#FFE61B', '#D67D3E', '#6867AC', '#FE7E6D']
		const cvs = document.querySelector('canvas')
		const canvasCtx = cvs.getContext('2d')
		const WIDTH = window.innerWidth
		const HEIGHT = 255
		cvs.height = HEIGHT
		cvs.width = WIDTH

		const audioElement = document.querySelector('audio')
		let audioCtx
		let analyserNode
		let mediaSource
		let gainNode

		audioCtx = new (window.AudioContext || window.webkitAudioContext)()
		analyserNode = audioCtx.createAnalyser()
		analyserNode.fft = 64
		gainNode = audioCtx.createGain()
		// 媒体音源！
		mediaSource = audioCtx.createMediaElementSource(audioElement)
		//第一个音源节点-绑定处理节点-处理节点-音频上下文！
		mediaSource.connect(gainNode)
		gainNode.connect(analyserNode)
		analyserNode.connect(audioCtx.destination)
		function doDraw() {
			if (audioElement.paused) {
				return
			}
			console.log(audioElement.currentTime)
			//frequencyBinCount 的值固定为 AnalyserNode 接口中fftSize值的一半. 该属性通常用于可视化的数据值的数量.
			let bufferLength = analyserNode.frequencyBinCount
			const dataArray = new Uint8Array(bufferLength)

			//AnalyserNode接口的getByteFrequencyData()方法将当到前频率数据复制传入的Uint8Array（无符号字节数组）中。和go的数据处理好像哈哈哈！
			analyserNode.getByteFrequencyData(dataArray)
			canvasCtx.clearRect(0, 0, WIDTH, HEIGHT) //每次循环都清除一次画布
			analyserNode.getByteFrequencyData(dataArray) // 调用
			gainNode.gain.value = 1
			let x = 0

			for (var i = 0; i < bufferLength; i++) {
				let barHeight = dataArray[i]
				var my_gradient = canvasCtx.createLinearGradient(0, 0, 0, 170)
				my_gradient.addColorStop(0, colors[Math.floor(Math.random() * colors.length)])
				my_gradient.addColorStop(1, 'transparent')
				canvasCtx.fillStyle = my_gradient
				canvasCtx.fillRect(x, HEIGHT / 2 - barHeight / 2, 5, barHeight / 2)
				canvasCtx.fillRect(x, HEIGHT / 2 - barHeight / 2, 5, barHeight)
				x += 5 + 3
			}
			requestAnimationFrame(doDraw)
		}
		audioElement.oncanplay = (e) => {
			doDraw()
		}
		audioElement.onplaying = (e) => {
			doDraw()
		}
		playBtn.onclick = () => {
			audioCtx.resume().then(() => {
				console.log(gainNode.gain.value)
				audioElement.paused ? audioElement.play() : audioElement.pause()
			})
		}
	</script>
</html>
